/**
 * 图片优化工具
 */

/**
 * 图片尺寸类型
 */
export enum ImageSize {
  Thumbnail = 'thumbnail', // 缩略图 150x150
  Small = 'small', // 小图 300x300
  Medium = 'medium', // 中图 600x600
  Large = 'large', // 大图 1200x1200
  Original = 'original', // 原图
}

/**
 * 云存储服务类型
 */
export enum CloudProvider {
  AliyunOSS = 'aliyun',
  TencentCOS = 'tencent',
  QiNiu = 'qiniu',
  AWS = 'aws',
}

/**
 * 图片优化配置
 */
interface ImageOptimizeConfig {
  provider?: CloudProvider;
  size?: ImageSize;
  quality?: number; // 图片质量 1-100
  format?: 'webp' | 'jpg' | 'png';
  width?: number;
  height?: number;
}

/**
 * 根据云服务生成图片处理参数
 */
function generateImageParams(
  provider: CloudProvider,
  config: ImageOptimizeConfig,
): string {
  const { size, quality = 80, format, width, height } = config;

  // 尺寸映射
  const sizeMap: Record<ImageSize, { width: number; height: number }> = {
    [ImageSize.Thumbnail]: { width: 150, height: 150 },
    [ImageSize.Small]: { width: 300, height: 300 },
    [ImageSize.Medium]: { width: 600, height: 600 },
    [ImageSize.Large]: { width: 1200, height: 1200 },
    [ImageSize.Original]: { width: 0, height: 0 },
  };

  const targetSize = size
    ? sizeMap[size]
    : { width: width || 0, height: height || 0 };

  switch (provider) {
    case CloudProvider.AliyunOSS:
      // 阿里云 OSS
      // https://help.aliyun.com/document_detail/44688.html
      if (targetSize.width === 0) return '';
      return `?x-oss-process=image/resize,m_fill,w_${targetSize.width},h_${targetSize.height}/quality,q_${quality}${format ? `/format,${format}` : ''}`;

    case CloudProvider.TencentCOS:
      // 腾讯云 COS
      // https://cloud.tencent.com/document/product/460/36540
      if (targetSize.width === 0) return '';
      return `?imageMogr2/thumbnail/${targetSize.width}x${targetSize.height}/quality/${quality}${format ? `/format/${format}` : ''}`;

    case CloudProvider.QiNiu:
      // 七牛云
      // https://developer.qiniu.com/dora/manual/1279/basic-processing-images-imageview2
      if (targetSize.width === 0) return '';
      return `?imageView2/1/w/${targetSize.width}/h/${targetSize.height}/q/${quality}${format ? `/format/${format}` : ''}`;

    case CloudProvider.AWS:
      // AWS S3 + CloudFront (需要配置 Lambda@Edge 或 CloudFront Functions)
      if (targetSize.width === 0) return '';
      return `?width=${targetSize.width}&height=${targetSize.height}&quality=${quality}${format ? `&format=${format}` : ''}`;

    default:
      return '';
  }
}

/**
 * 检测是否是视频文件
 */
function isVideoFile(url: string): boolean {
  const videoExtensions = [
    '.mp4',
    '.mov',
    '.avi',
    '.wmv',
    '.flv',
    '.webm',
    '.m4v',
  ];
  const lowerUrl = url.toLowerCase();
  return videoExtensions.some((ext) => lowerUrl.includes(ext));
}

/**
 * 检测是否是图片文件
 */
function isImageFile(url: string): boolean {
  const imageExtensions = [
    '.jpg',
    '.jpeg',
    '.png',
    '.gif',
    '.webp',
    '.bmp',
    '.svg',
  ];
  const lowerUrl = url.toLowerCase();
  return imageExtensions.some((ext) => lowerUrl.includes(ext));
}

/**
 * 优化图片 URL
 * @param url 原始图片 URL
 * @param config 优化配置
 * @returns 优化后的图片 URL
 */
export function optimizeImageUrl(
  url: string | undefined,
  config: ImageOptimizeConfig = {},
): string | undefined {
  if (!url) return undefined;

  // 已经是 base64 或 blob，不处理
  if (url.startsWith('data:') || url.startsWith('blob:')) {
    return url;
  }

  // 如果是视频文件，不应用图片处理参数
  if (isVideoFile(url)) {
    return url;
  }

  // 如果无法识别文件类型（没有明确的图片扩展名），返回原 URL
  // 这样更安全，避免对未知类型文件应用图片处理参数
  if (!isImageFile(url)) {
    return url;
  }

  const {
    provider = CloudProvider.AliyunOSS, // 默认阿里云
    size = ImageSize.Small,
    ...restConfig
  } = config;

  const params = generateImageParams(provider, { size, ...restConfig });

  // 如果 URL 已经有参数，追加；否则直接添加
  if (!params) return url;

  if (url.includes('?')) {
    return `${url}&${params.slice(1)}`; // 去掉开头的 ?
  }

  return `${url}${params}`;
}

/**
 * 为列表缩略图优化 URL
 * @param url 原始图片 URL
 * @param provider 云服务提供商
 */
export function getThumbnailUrl(
  url: string | undefined,
  provider?: CloudProvider,
): string | undefined {
  return optimizeImageUrl(url, {
    provider,
    size: ImageSize.Thumbnail,
    quality: 80,
    format: 'webp',
  });
}

/**
 * 为详情页优化 URL
 * @param url 原始图片 URL
 * @param provider 云服务提供商
 */
export function getDetailImageUrl(
  url: string | undefined,
  provider?: CloudProvider,
): string | undefined {
  return optimizeImageUrl(url, {
    provider,
    size: ImageSize.Large,
    quality: 85,
    format: 'webp',
  });
}

/**
 * 批量优化图片 URL
 */
export function batchOptimizeImageUrls(
  urls: (string | undefined)[],
  config?: ImageOptimizeConfig,
): (string | undefined)[] {
  return urls.map((url) => optimizeImageUrl(url, config));
}

/**
 * 图片预加载
 * @param urls 图片 URL 列表
 * @param limit 并发限制，默认 3
 */
export function preloadImages(urls: string[], limit = 3): Promise<void> {
  return new Promise((resolve) => {
    if (!urls || urls.length === 0) {
      resolve();
      return;
    }

    let loaded = 0;
    let index = 0;

    const loadNext = () => {
      if (index >= urls.length) return;

      const url = urls[index++];
      const img = new Image();

      img.onload = img.onerror = () => {
        loaded++;
        if (loaded === urls.length) {
          resolve();
        } else {
          loadNext();
        }
      };

      img.src = url;
    };

    // 启动并发加载
    for (let i = 0; i < Math.min(limit, urls.length); i++) {
      loadNext();
    }
  });
}

/**
 * 检测是否支持 WebP
 */
export function isSupportWebP(): Promise<boolean> {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => resolve(img.width === 1);
    img.onerror = () => resolve(false);
    img.src =
      '';
  });
}

/**
 * 获取视频封面 URL（云存储截帧）
 */
export function getVideoCoverUrl(
  videoUrl: string | undefined,
  provider: CloudProvider = CloudProvider.AliyunOSS,
): string | undefined {
  if (!videoUrl) return undefined;

  switch (provider) {
    case CloudProvider.AliyunOSS:
      return `${videoUrl}?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast`;

    case CloudProvider.TencentCOS:
      return `${videoUrl}?ci-process=snapshot&time=0&format=jpg`;

    case CloudProvider.QiNiu:
      return `${videoUrl}?vframe/jpg/offset/0`;

    default:
      return undefined;
  }
}
